#include <stdbool.h>
#include <stdio.h>
#include <string.h>

#include "parcel.h"
#include "sqlite3.h"

static sqlite3* db;

static bool opendb()
{
    int ret = sqlite3_open(DB_NAME, &db);

    if (ret != SQLITE_OK) {
        printf("[%s %d]: %s\n", __FILE__, __LINE__, sqlite3_errmsg(db));
        return false;
    }

    return true;
}

static void closedb()
{
    if (db != NULL) {
        sqlite3_close(db);
    }
}

bool save_parcel(Form* form)
{
    if (!opendb()) {
        return false;
    }

    char sql1[MAX_SQL_LEN / 2] = "INSERT INTO ";
    strcat(sql1, TABLE_NAME);
    strcat(sql1, " (");

    char sql2[MAX_SQL_LEN / 2] = " VALUES (";

    while (form->next != NULL) {
        form = form->next;

        strcat(sql1, "'");
        strcat(sql1, form->name);
        strcat(sql1, "'");

        if (strcmp(form->name, "isOut") == 0) {
            strcat(sql2, form->value);
        } else {
            strcat(sql2, "'");
            strcat(sql2, form->value);
            strcat(sql2, "'");
        }

        if (form->next != NULL) {
            strcat(sql1, ",");
            strcat(sql2, ",");
        } else {
            strcat(sql1, ")");
            strcat(sql2, ")");
        }
    }

    strcat(sql1, sql2);

    char* errmsg = NULL;
    int ret = sqlite3_exec(db, sql1, NULL, NULL, &errmsg);

    if (ret != SQLITE_OK) {
        printf("[%s %d]: %s\n", __FILE__, __LINE__, errmsg);
        sqlite3_free(errmsg);
        return false;
    }

    closedb();
    return true;
}

int find_all(char json[], int max_json_len)
{
    sqlite3_stmt* stmt = NULL;
    char sql[MAX_SQL_LEN] = "SELECT * FROM ";

    strcat(sql, TABLE_NAME);
    strcat(sql, ";");

    opendb();

    int ret = sqlite3_prepare(db, sql, strlen(sql), &stmt, NULL);

    if (ret != SQLITE_OK) {
        printf("[%s %d]: %s\n", __FILE__, __LINE__, sqlite3_errmsg(db));
        return 0;
    }

    memset(json, 0, max_json_len);

    json[0] = '[';
    char is_out_str[2] = { 0 };
    int is_out;
    int count = 0;

    while (sqlite3_step(stmt) == SQLITE_ROW) {
        ++count;
        strcat(json, "{");

        strcat(json, "\"");
        strcat(json, "expressNum");
        strcat(json, "\": ");
        strcat(json, "\"");
        strcat(json, sqlite3_column_text(stmt, 0));
        strcat(json, "\"");
        strcat(json, ",");

        strcat(json, "\"");
        strcat(json, "logisticsNum");
        strcat(json, "\": ");
        strcat(json, "\"");
        strcat(json, sqlite3_column_text(stmt, 1));
        strcat(json, "\"");
        strcat(json, ",");

        strcat(json, "\"");
        strcat(json, "barcode");
        strcat(json, "\": ");
        strcat(json, "\"");
        strcat(json, sqlite3_column_text(stmt, 2));
        strcat(json, "\"");
        strcat(json, ",");

        strcat(json, "\"");
        strcat(json, "sender");
        strcat(json, "\":");
        strcat(json, "\"");
        strcat(json, sqlite3_column_text(stmt, 3));
        strcat(json, "\"");
        strcat(json, ",");

        strcat(json, "\"");
        strcat(json, "recipient");
        strcat(json, "\": ");
        strcat(json, "\"");
        strcat(json, sqlite3_column_text(stmt, 4));
        strcat(json, "\"");
        strcat(json, ",");

        strcat(json, "\"");
        strcat(json, "sendingAddr");
        strcat(json, "\": ");
        strcat(json, "\"");
        strcat(json, sqlite3_column_text(stmt, 5));
        strcat(json, "\"");
        strcat(json, ",");

        strcat(json, "\"");
        strcat(json, "recivingAddr");
        strcat(json, "\": ");
        strcat(json, "\"");
        strcat(json, sqlite3_column_text(stmt, 6));
        strcat(json, "\"");
        strcat(json, ",");

        strcat(json, "\"");
        strcat(json, "currentAddr");
        strcat(json, "\": ");
        strcat(json, "\"");
        strcat(json, sqlite3_column_text(stmt, 7));
        strcat(json, "\"");
        strcat(json, ",");

        strcat(json, "\"");
        strcat(json, "nextAddr");
        strcat(json, "\": ");
        strcat(json, "\"");
        strcat(json, sqlite3_column_text(stmt, 8));
        strcat(json, "\"");
        strcat(json, ",");

        strcat(json, "\"");
        strcat(json, "isOut");
        strcat(json, "\": ");

        is_out = sqlite3_column_int(stmt, 9);
        is_out_str[0] = is_out + '0';
        is_out_str[1] = '\0';
        strcat(json, is_out_str);

        strcat(json, "},");
    }

    sqlite3_finalize(stmt);

    /* remove the redundant , */
    json[strlen(json) - 1] = '\0';
    strcat(json, "]");

    closedb();

    return count;
}
